package io.seata.order.service.impl;

import feign.FeignException;
import io.seata.common.dto.AccountDTO;
import io.seata.common.dto.OrderDTO;
import io.seata.common.dto.StorageDTO;
import io.seata.common.enums.RspStatusEnum;
import io.seata.common.exception.DefaultException;
import io.seata.common.response.ObjectResponse;
import io.seata.order.client.AccountClient;
import io.seata.order.client.StorageClient;
import io.seata.order.entity.Order;
import io.seata.order.mapper.OrderMapper;
import io.seata.order.service.OrderService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

/**
 * @author ZengRJ
 */
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    @Resource
    private AccountClient accountClient;

    @Resource
    private StorageClient storageClient;

    @Resource
    private OrderMapper orderMapper;

    @Override
    @GlobalTransactional(timeoutMills = 60000 * 60)
    public ObjectResponse<OrderDTO> create(OrderDTO orderDTO) {
        ObjectResponse<OrderDTO> objectResponse = new ObjectResponse<>();
        Order order = new Order();
        BeanUtils.copyProperties(orderDTO, order);
        // 创建订单
        orderMapper.insert(order);
        try {
            AccountDTO accountDTO = new AccountDTO();
            accountDTO.setUserId(orderDTO.getUserId());
            accountDTO.setMoney(orderDTO.getMoney());
            // 扣用户余额
            accountClient.deduct(accountDTO);

            StorageDTO storageDTO = new StorageDTO();
            storageDTO.setCommodityCode(orderDTO.getCommodityCode());
            storageDTO.setCount(orderDTO.getCount());
            // 扣库存
            storageClient.deduct(storageDTO);
        } catch (FeignException e) {
            log.error("下单失败，原因:{}", e.contentUTF8(), e);
            throw new DefaultException("下单失败", e);
        }

        objectResponse.setStatus(RspStatusEnum.SUCCESS.getCode());
        objectResponse.setMessage(RspStatusEnum.SUCCESS.getMessage());
        objectResponse.setData(orderDTO);
        return objectResponse;
    }
}
